home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
301-325
/
325
/
keymacro
/
keymacro.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-14
|
14KB
|
755 lines
#include <libraries/arpbase.h>
#include <arpfunctions.h>
#include <stdio.h>
#include <ctype.h>
#include "KeyMacro.h"
char *CLI_Template = "STARTUP/K,QUIT/S,INFO/S";
char *CLI_Help = "\nUsage: \33[1mKeyMacro\33[0m [STARTUP <File>] [QUIT] [INFO]\n";
#define ARG_STARTUP 1
#define ARG_QUIT 2
#define ARG_INFO 3
#define ARG_UPDATE 4
#define From_CLI (ThatsMe -> pr_CLI)
struct MXMBase *MXMBase;
struct MSeg *MSeg;
struct MacroKey *KeyList;
struct KeyAlias KeyTab[22] =
{
{"TAB", 0x42},
{"ESC", 0x45},
{"SPACE", 0x40},
{"RETURN", 0x44},
{"ENTER", 0x43},
{"DEL", 0x46},
{"BACKSPACE", 0x41},
{"HELP", 0x5F},
{"LEFT", 0x4F},
{"RIGHT", 0x4E},
{"UP", 0x4C},
{"DOWN", 0x4D},
{"F1", 0x50},
{"F2", 0x51},
{"F3", 0x52},
{"F4", 0x53},
{"F5", 0x54},
{"F6", 0x55},
{"F7", 0x56},
{"F8", 0x57},
{"F9", 0x58},
{"F10", 0x59}
};
struct KeyAlias QualifierTab[9] =
{
{"NONE", 0},
{"CTRL", IEQUALIFIER_CONTROL},
{"NUMPAD", IEQUALIFIER_NUMERICPAD},
{"LSHIFT", IEQUALIFIER_LSHIFT},
{"RSHIFT", IEQUALIFIER_RSHIFT},
{"LALT", IEQUALIFIER_LALT},
{"RALT", IEQUALIFIER_RALT},
{"LAMIGA", IEQUALIFIER_LCOMMAND},
{"RAMIGA", IEQUALIFIER_RCOMMAND}
};
#asm
_LVORawDoFmt EQU $FFFFFDF6
StuffChar: MOVE.B D0,(A3)+
RTS
XDEF _Format
_Format: MOVE.L 4(SP),D1
MOVE.L 8(SP),D0
LEA 12(SP),A1
MOVEM.L A0-A3,-(SP)
MOVE.L D1,A3
MOVE.L D0,A0
LEA StuffChar(PC),A2
MOVE.L 4,A6
JSR _LVORawDoFmt(A6)
MOVEM.L (SP)+,A0-A3
CLR.L D0
RTS
#endasm
void *
SendCustomMsg(scm_Msg)
struct MacroMessage *scm_Msg;
{
struct MacroMessage *scm_TempMsg = (struct MacroMessage *)AllocRem(sizeof(struct MacroMessage),MEMF_PUBLIC | MEMF_CLEAR);
if(scm_TempMsg)
{
CopyMem(scm_Msg,scm_TempMsg,sizeof(struct MacroMessage));
scm_TempMsg -> mm_Message . mn_Node . ln_Name = (char *)scm_TempMsg;
scm_TempMsg -> mm_Message . mn_ReplyPort = NULL;
scm_TempMsg -> mm_Message . mn_Length = sizeof(struct MacroMessage);
PutMsg(&MSeg -> Port,scm_TempMsg);
}
return((void *)scm_TempMsg);
}
UBYTE *
GetToken(s,start)
UBYTE *s;
long *start;
{
static UBYTE buffer[256];
long i,j,end = 0,quote = FALSE,maxlen = strlen(s);
char t;
if(maxlen > 255)
maxlen = 255;
if(*start > strlen(s) - 1 || !strlen(s) || !s)
return(NULL);
for(i = *start ; i <= maxlen ; i++)
{
if(!end && (s[i] == ' ' || s[i] == '\t'))
{
while((s[i] == ' ' || s[i] == '\t') && i < maxlen)
{
i++;
(*start)++;
}
}
t = s[i];
if(!end && t == '+')
{
(*start)++;
continue;
}
if(!end && t == '=')
{
strcpy(buffer,"=");
(*start)++;
return(buffer);
}
if(s[i] == '\\' && s[i + 1] == '\"')
{
i += 2;
end = i - *start + 1;
t = s[i];
}
if(t == '\"' && !quote)
{
quote = TRUE;
(*start)++;
end++;
continue;
}
if((t == '+' || t == '=' || t == ' ' || t == '\t' || t == ';') && quote)
{
end++;
continue;
}
if((t == '+' || t == '\n' || t == '=' || t == ' ' || t == 0) || (t == '\"' && quote) || (t == ';' && !quote))
{
if(t == ';' && !end)
return(NULL);
if(t == '\"')
{
strncpy(buffer,s + *start,end - 1);
buffer[end - 1] = 0;
}
else
{
strncpy(buffer,s + *start,end);
buffer[end] = 0;
}
(*start) += end;
return(buffer);
}
end++;
}
return(NULL);
}
struct MacroKey *
AddMacroKey(MacroKey)
struct MacroKey *MacroKey;
{
struct MacroKey *TheKey = NULL;
long i;
for(i = 0 ; i < MSeg -> NumMacros ; i++)
{
if(KeyList[i] . mk_Type == MK_UNUSED)
{
TheKey = &KeyList[i];
break;
}
}
if(!TheKey)
return(NULL);
CopyMem(MacroKey,TheKey,sizeof(struct MacroKey));
return(TheKey);
}
BOOL
Interprete(String,Line)
UBYTE *String;
long Line;
{
ULONG Qualifier = 0;
ULONG Code = -1;
struct InputEvent FakeEvent;
struct MacroKey NewKey;
long Start = 0,Key = FALSE,QuitLoop = FALSE,i,KeyCount = 0;
UBYTE *Token,*CommandString,*WindowName = NULL,Recognized = FALSE;
UBYTE MessBuff[256],KeyBuff1[40],KeyBuff2[40];
if(String[strlen(String) - 1] == '\n')
String[strlen(String) - 1] = 0;
if(Token = GetToken(String,&Start))
{
if(!UStrCmp("KEY",Token))
Key = TRUE;
if(UStrCmp("COMMAND",Token) && !Key)
{
Format(MessBuff,"Line %ld: Unknown keyword:\n\n'%s'",Line,String);
PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
}
else
return(TRUE);
FOREVER
{
if(Token = GetToken(String,&Start))
{
QuitLoop = TRUE;
for(i = 0 ; i < 9 ; i++)
{
if(!UStrCmp(QualifierTab[i] . ka_Name,Token))
{
Recognized = TRUE;
QuitLoop = FALSE;
Qualifier |= QualifierTab[i] . ka_Key;
}
}
}
else
break;
if(QuitLoop)
break;
}
if(!Recognized)
{
Format(MessBuff,"Line %ld: Didn't recognize qualifier:\n\n'%s'",Line,String);
PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
if(Token)
goto JumpIn;
if(Token = GetToken(String,&Start))
{
JumpIn: for(i = 0 ; i < 22 ; i++)
{
if(!UStrCmp(KeyTab[i] . ka_Name,Token))
{
Code = KeyTab[i] . ka_Key;
goto Next;
}
}
if(InvertKey(Token[0],&FakeEvent,IK_USEIKM,NULL))
Code = FakeEvent . ie_Code;
}
if(Code == -1)
{
Format(MessBuff,"Line %ld: Didn't recognize key:\n\n'%s'",Line,String);
PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
Next: FOREVER
{
if(Token = GetToken(String,&Start))
{
if(!UStrCmp("=",Token))
break;
}
else
{
Format(MessBuff,"Line %ld: Statement '=' missing:\n\n'%s'",Line,String);
PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
}
if(Token = GetToken(String,&Start))
strcpy(KeyBuff1,Token);
else
{
Format(MessBuff,"Line %ld: Didn't find macro:\n\n'%s'",Line,String);
PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
if(Key)
goto AddIt;
if(!(Token = GetToken(String,&Start)))
goto AddIt;
if(UStrCmp("WINDOW",Token))
{
Format(MessBuff,"Line %ld: Didn't recognize 'WINDOW' statement:\n\n'%s'",Line,String);
PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
if(!(Token = GetToken(String,&Start)))
{
Format(MessBuff,"Line %ld: Didn't find window title:\n\n'%s'",Line,String);
PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
if(!(WindowName = (UBYTE *)AllocRem(strlen(Token) + 1,MEMF_PUBLIC)))
{
PopRequest(NULL,"KeyMacro Problem:","Can't allocate memory chunk!",NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
strcpy(WindowName,Token);
AddIt: for(i = 0 ; i < strlen(KeyBuff1) ; i++)
{
UBYTE c;
if(KeyBuff1[i] != '\\')
{
KeyBuff2[KeyCount++] = KeyBuff1[i];
continue;
}
if(i == strlen(KeyBuff1) - 1)
break;
i++;
c = 0;
switch(ToUpper(KeyBuff1[i]))
{
case 'U': c = KC_CURSORUP;
break;
case 'D': c = KC_CURSORDOWN;
break;
case 'L': c = KC_CURSORLEFT;
break;
case 'R': c = KC_CURSORRIGHT;
break;
case 'H': c = KC_HELP;
break;
case 'B': c = 8;
break;
case 'E': c = 127;
break;
case 'F': if(i == strlen(KeyBuff1) - 1)
break;
i++;
if(!isdigit(KeyBuff1[i]))
break;
if(!KeyBuff1[i] == '1')
{
c = KC_FKEY1 + KeyBuff1[i] - '1';
break;
}
if(i == strlen(KeyBuff1) - 1)
break;
i++;
if(!isdigit(KeyBuff1[i]))
{
c = KC_FKEY1;
break;
}
if(KeyBuff1[i] != '0')
break;
c = KC_FKEY10;
break;
case 'N': c = '\n';
break;
case '\\': c = '\\';
break;
default: c = KeyBuff1[i];
break;
}
if(c)
KeyBuff2[KeyCount++] = c;
}
KeyBuff2[KeyCount] = 0;
if(!(CommandString = (UBYTE *)AllocRem(strlen(KeyBuff2) + 1,MEMF_PUBLIC)))
{
PopRequest(NULL,"KeyMacro Problem:","Can't allocate memory chunk!",NULL,"Continue?",FALSE,NULL);
FreeRem(WindowName);
return(FALSE);
}
strcpy(CommandString,KeyBuff2);
setmem(&NewKey,sizeof(struct MacroKey),0);
NewKey . mk_CommandKey = Code;
NewKey . mk_CommandQualifier = Qualifier;
NewKey . mk_String = CommandString;
NewKey . mk_Window = WindowName;
if(Key)
NewKey . mk_Type = MK_WORD;
else
NewKey . mk_Type = MK_COMMAND;
if(AddMacroKey(&NewKey))
return(TRUE);
Format(MessBuff,"Line %ld: Key macro table full.",Line);
PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
BOOL
UpdateList(Name)
char *Name;
{
char LineBuff[256];
long LineNum = 1;
FILE *ConfigFile;
if(!Name)
Name = "S:KeyMacro.config";
if(!(KeyList = (struct MacroKey *)AllocRem(sizeof(struct MacroKey) * MAXMACROS,MEMF_PUBLIC | MEMF_CLEAR)))
{
PopRequest(NULL,"KeyMacro Problem:","Can't allocate memory chunk!",NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
MSeg -> NumMacros = MAXMACROS;
if(ConfigFile = fopen(Name,"r"))
{
while(fgets(LineBuff,256,ConfigFile))
{
if(!Interprete(LineBuff,LineNum++))
{
fclose(ConfigFile);
FreeRem(KeyList);
return(FALSE);
}
}
fclose(ConfigFile);
}
else
{
PopRequest(NULL,"KeyMacro Problem:","Couldn't open configuration file!",NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
return(TRUE);
}
Chk_Abort() { return(0); }
void
main(argc,argv)
long argc;
char *argv[];
{
struct Process *ThatsMe = (struct Process *)FindTask(NULL);
BOOL Created = FALSE;
char *FileName = argv[ARG_STARTUP];
long i;
if(!From_CLI)
FileName = NULL;
if(!(MXMBase = (struct MXMBase *)OpenLibrary("mxm.library",0)))
{
if(From_CLI)
Puts("\33[1mKeyMacro:\33[0m You need the \33[1mmxm.library\33[0m to run this program.");
exit(5);
}
MSeg = (struct MSeg *)FindPort(PORTNAME);
if(argv[ARG_INFO])
{
Printf("\n\33[1m\33[33mKeyMacro\33[31m\33[0m the Amiga macro key handler.\n\n");
Printf(" This program may be non-commercially\n");
Printf(" re-distributed!\n\n");
Printf("\33[1m\33[33mAuthor\33[31m\33[0m - Olaf Barthel of MXM\n");
Printf(" Brabeckstrasse 35\n");
Printf(" D-3000 Hannover 71\n\n");
Printf(" Federal Republic of Germany.\n\n");
CloseLibrary(MXMBase);
exit(0);
}
if(argv[ARG_QUIT])
{
Printf("Removing \33[1m\33[33mKeyMacro\33[31m\33[0m, ");
if(!MSeg)
{
Printf("failed!\7\n");
CloseLibrary(MXMBase);
exit(0);
}
MSeg -> Father = (struct Task *)FindTask(NULL);
if(MSeg -> Child)
{
Signal(MSeg -> Child,SIG_CLOSE);
Wait(SIG_CLOSE);
}
RemPort(&MSeg -> Port);
FreeRem(MSeg -> Port . mp_Node . ln_Name);
if(MSeg -> Segment)
UnLoadSeg(MSeg -> Segment);
if(MSeg -> MacroList)
{
for(i = 0 ; i < MSeg -> NumMacros ; i++)
{
if(MSeg -> MacroList[i] . mk_Type == MK_UNUSED)
continue;
if(MSeg -> MacroList[i] . mk_String)
FreeRem(MSeg -> MacroList[i] . mk_String);
if(MSeg -> MacroList[i] . mk_Window)
FreeRem(MSeg -> MacroList[i] . mk_Window);
}
FreeRem(MSeg -> MacroList);
}
FreeRem(MSeg);
Printf("OK.\n");
CloseLibrary(MXMBase);
exit(0);
}
if(!MSeg)
{
if(MSeg = (struct MSeg *)AllocRem(sizeof(struct MSeg),MEMF_PUBLIC | MEMF_CLEAR))
{
MSeg -> Port . mp_Flags = PA_IGNORE;
MSeg -> Port . mp_Node . ln_Pri = 0;
MSeg -> Port . mp_Node . ln_Type= NT_MSGPORT;
MSeg -> Port . mp_Node . ln_Name= AllocRem(sizeof(PORTNAME),MEMF_PUBLIC);
MSeg -> Child = NULL;
MSeg -> Father = (struct Task *)FindTask(NULL);
MSeg -> SegSize = sizeof(struct MSeg);
MSeg -> RingBack = SIGBREAKF_CTRL_C;
MSeg -> Revision = REVISION;
NewList(&MSeg -> Port . mp_MsgList);
if(From_CLI)
{
Printf("\33[1m\33[33mKeyMacro v1.%ld \33[31m\33[0m(C) Copyright 1989, 1990 by \33[4mMXM\33[0m.\n",REVISION);
Printf("Installing \33[33m\33[1mKeyMacro\33[0m\33[31m, ");
}
if(MSeg -> Port . mp_Node . ln_Name)
strcpy(MSeg -> Port . mp_Node . ln_Name,PORTNAME);
else
{
if(From_CLI)
Printf("failed!\n");
CloseLibrary(MXMBase);
exit(20);
}
MSeg -> Segment = (BPTR)LoadSeg("KeyMacro-Handler");
if(!MSeg -> Segment)
MSeg -> Segment = (BPTR)LoadSeg("L:KeyMacro-Handler");
if(!MSeg -> Segment)
{
if(From_CLI)
Printf("unable to find \33[33mL:KeyMacro-Handler\33[31m\7!\n");
FreeRem(MSeg -> Port . mp_Node . ln_Name);
FreeRem(MSeg);
}
else
{
AddPort(&MSeg -> Port);
CreateProc("KeyMacro-Handler",10,MSeg -> Segment,4096);
Wait(SIGBREAKF_CTRL_C);
if(!MSeg -> Child)
{
if(From_CLI)
Printf("\33[33mFAILED!\33[31m (care to retry?)\n");
RemPort(&MSeg -> Port);
FreeRem(MSeg -> Port . mp_Node . ln_Name);
if(MSeg -> Segment)
UnLoadSeg(MSeg -> Segment);
FreeRem(MSeg);
CloseLibrary(MXMBase);
exit(20);
}
else
{
if(From_CLI)
Printf("initializing, ");
InvertKey(NULL,NULL,IK_USEIKM | IK_BUILDLIST,NULL);
if(From_CLI)
Puts("Okay.");
else
PopRequest(NULL,"KeyMacro Info:","\33[1mKeyMacro\33[0m installed.",NULL,"Continue?",FALSE,NULL);
Created = TRUE;
}
}
}
}
if(UpdateList(FileName))
{
if(Created)
{
MSeg -> NumMacros = MAXMACROS;
MSeg -> MacroList = KeyList;
}
else
{
struct MacroMessage UpdateMsg;
UpdateMsg . mm_Type = MM_UPDATE;
UpdateMsg . mm_NumMacros= MAXMACROS;
UpdateMsg . mm_MacroList= KeyList;
SendCustomMsg(&UpdateMsg);
if(From_CLI)
Printf("\33[1mKeyMacro:\33[0m Updating macro keys...\n");
}
}
else
{
CloseLibrary(MXMBase);
exit(10);
}
CloseLibrary(MXMBase);
}